I am trying to create a polyfill for the call, apply and bind methods.
const user = {
firstName: "Christopher",
lastName: "Nolan",
};
const fullName = function (place, country) {
console.log(
`${this.firstName} ${this.lastName} is from ${place}, ${country}.`
);
};
// Using a call method
fullName.call(user, "London", "UK");
// Re-creating a call method with the name of "_call"
Function.prototype._call = function (...args) {
const funcObj = this;
const params = args.slice(1);
return (function () {
const obj = args[0];
// How can I point out the obj to "this" keyword inside a funcObj without using the bind method as I mentioned below.
return funcObj.bind(obj, ...params)();
})();
};
fullName._call(user, "London", "UK");
Yes. Just use
var myObject = this;
I understand the problem you might be having. Sometimes by the time you wish to use the 'this' object the context of 'this' has changed. Some people use
var that = this;
Here's some more reading for you that goes a bit deeper.
https://dbwriteups.wordpress.com/2017/04/08/what-does-that-this-in-javascript-mean/
I'm not sure this is a great implementation, but you could take advantage of the fact that for an object method the scope is automatically set to the object upon which it was invoked.
With that in mind you could create an object using the scope as the prototype and add the original function as a method, then invoke the method.
const user = {
firstName: "Christopher",
lastName: "Nolan",
};
const fullName = function (place, country) {
console.log(
`${this.firstName} ${this.lastName} is from ${place}, ${country}.`
);
};
Function.prototype._call = function (scope, ...args) {
// symbol for the method name to avoid name collisions
const symbol = Symbol();
// create a new object from scope with the original function (this) as a method
const temp = Object.create(scope, {[symbol]: { value: this }});
// inside the method "this" will point to "temp" which is (effectively) "scope"
return temp[symbol](...args);
}
fullName._call(user, 'London', 'UK');